package cn.finder0519.applist;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.text.Collator;
import java.util.*;

public class MainActivity extends AppCompatActivity {

    static final String PKG_TRACEUR = "com.android.traceur";

    List<MyAppInfo> myAppInfoList;
    MyAppListAdapter adapter;
    private String appName;
    private String pkgName;
    private String appVer;
    FloatingActionButton floatingActionButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        doRefresh();

        ListView listView = findViewById(R.id.list1);
        adapter = new MyAppListAdapter();
        listView.setAdapter(adapter);

        registerForContextMenu(listView);

        listView.setOnItemClickListener((adapterView, view, i, l) -> {
            Intent intent = getPackageManager().getLaunchIntentForPackage(myAppInfoList.get(i).getPkgName());
            if (intent != null) {
                startActivity(intent);
            }
        });

        listView.setOnItemLongClickListener((adapterView, view, i, l) -> {
            appName = myAppInfoList.get(i).getAppName();
            pkgName = myAppInfoList.get(i).getPkgName();
            appVer = myAppInfoList.get(i).getAppVer();
            return false;
        });

        floatingActionButton = findViewById(R.id.fab_refresh);
        ColorStateList fabForeColor;
        int curNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
        if (curNightMode == Configuration.UI_MODE_NIGHT_YES) {
            fabForeColor = ContextCompat.getColorStateList(this, R.color.black);
        } else {
            fabForeColor = ContextCompat.getColorStateList(this, R.color.white);
        }

        floatingActionButton.setImageTintList(fabForeColor);

        floatingActionButton.setOnClickListener(v -> {
            doRefresh();
            adapter.notifyDataSetChanged();
            Toast.makeText(MainActivity.this, getResources().getString(R.string.number_of_apps, String.valueOf(myAppInfoList.size())), Toast.LENGTH_SHORT).show();
        });
    }

    private List<MyAppInfo> getAvailableApps() throws PackageManager.NameNotFoundException {
        PackageManager packageManager = getPackageManager();

        List<ApplicationInfo> installedApps = packageManager.getInstalledApplications(0);

        List<MyAppInfo> myAppInfoList = new ArrayList<>();

        for (ApplicationInfo applicationInfo : installedApps) {
            Intent appLaunchIntent = packageManager.getLaunchIntentForPackage(applicationInfo.packageName);
            if (appLaunchIntent != null && packageManager.resolveActivity(appLaunchIntent, 0) != null) {
                String pkgName = applicationInfo.packageName;
                String appName = packageManager.getApplicationLabel(applicationInfo).toString();
                String appVer = packageManager.getPackageInfo(pkgName, 0).versionName;
                Drawable appIcon = packageManager.getApplicationIcon(applicationInfo);
                if (!pkgName.equals(getPackageName()) && !pkgName.equals(PKG_TRACEUR)) {
                    myAppInfoList.add(new MyAppInfo(pkgName, appName, appVer, appIcon));
                }
            }
        }

        myAppInfoList.sort((o1, o2) -> {
            Comparator<Object> comparator = Collator.getInstance(Locale.CHINA);
            return comparator.compare(o1.getAppName(), o2.getAppName());
        });

        return myAppInfoList;

    }

    @Override
    public void onBackPressed() {
        finish();
    }

    @Override
    public void onResume() {
        doRefresh();
        adapter.notifyDataSetChanged();
        super.onResume();
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.setHeaderTitle(getResources().getString(R.string.version, appVer));
        menu.add(Menu.NONE, 1, Menu.NONE, getResources().getString(R.string.copy_to_clipboard));
        menu.add(Menu.NONE, 2, Menu.NONE, getResources().getString(R.string.app_info));
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        if (item.getItemId() == 1) {
            ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(appName);
            stringBuilder.append("\n");
            stringBuilder.append(getResources().getString(R.string.package_name, pkgName));
            stringBuilder.append("\n");
            stringBuilder.append(getResources().getString(R.string.version, appVer));
            stringBuilder.append("\n");
            ClipData clipData = ClipData.newPlainText("AppInfo", stringBuilder);
            clipboardManager.setPrimaryClip(clipData);
            Toast.makeText(this, getResources().getString(R.string.copied), Toast.LENGTH_SHORT).show();
        }
        if (item.getItemId() == 2) {
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.fromParts("package", pkgName, null));
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
            return true;
        }
        return super.onContextItemSelected(item);
    }

    class MyAppListAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return myAppInfoList.size();
        }

        @Override
        public Object getItem(int i) {
            return myAppInfoList.get(i);
        }

        @Override
        public long getItemId(int i) {
            return i;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.list_item, parent, false);
                holder = new ViewHolder();
                holder.textView1 = convertView.findViewById(R.id.app_name);
                holder.textView2 = convertView.findViewById(R.id.pkg_name);
                holder.imageView = convertView.findViewById(R.id.app_icon);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.textView1.setText(myAppInfoList.get(position).getAppName());
            holder.textView2.setText(myAppInfoList.get(position).getPkgName());
            holder.imageView.setImageDrawable(myAppInfoList.get(position).getAppIcon());
            return convertView;
        }

        class ViewHolder {
            TextView textView1;
            TextView textView2;
            ImageView imageView;
        }
    }

    private void doRefresh() {
        try {
            myAppInfoList = getAvailableApps();
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(e);
        }

    }

}